#!/usr/bin/python3
#
# Copyright 2012 Robert Muth
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 3
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

"""
Main hocuspocus script
"""

# python includes
import imp
import logging
import multiprocessing
import os
import sys

import tornado.autoreload
import tornado.options
import tornado.ioloop
import tornado.web
import tornado.template


VERSION = "3.0"

# ======================================================================

tornado.options.define("port",
                       default=8888,
                       type=int,
                       help="server port")

tornado.options.define("tasks",
                       default=4,
                       type=int,
                       help="size of task pool")

tornado.options.define("name",
                       default="no-name",
                       type=str,
                       help="name/purpose of this machine")

tornado.options.define("css_style_file",
                       default="static/hocuspocus.css",
                       type=str,
                       help="style file path")

OPTIONS = tornado.options.options

# ======================================================================

class MainHandler(tornado.web.RequestHandler):
    """ Handler for root path - simply redirects to /about
    """
    def initialize(self, template_args):
        logging.debug("main hander init")


    @tornado.web.asynchronous
    def get(self):
        self.redirect("/about/")


# TODO: make these configurable
TITLE_PLUGINS = ["pulse",
                 "media",
                 "webcam",
                 "vlc",
                 "chrome",
                 "system",
                 "alarm",
                 "quodlibet",
                 "task",
                 ]

# do not show these in title bar
SILENT_PLUGINS = ["about",
                  ]

ALL_PLUGINS =  TITLE_PLUGINS + SILENT_PLUGINS


# These args are passed to all

def GetBaseTemplateArgs():
    return {
        "service_name": OPTIONS.name,
        "version": VERSION,
        "plugins": [ {"name": name, "url": name + "/"}
                     for name  in TITLE_PLUGINS],
        "css_style_file": OPTIONS.css_style_file,
        }


def LoadPlugins(plugins):
    modules = []
    for name in plugins:
        mod = imp.load_source(name, "Plugins/%s.py" % name)
        modules.append((name, mod))
    return modules


def GetHandlers(plugins):
    handlers = []
    handlers.append(("/",
                     MainHandler,
                     # this is passed to the initialize() handler function
                     {"template_args": GetBaseTemplateArgs()}))

    for name, mod in plugins:
        template_args = GetBaseTemplateArgs()
        template_args["plugin_name"] = name
        template_args["plugin_extra"] = ""
        logging.info("preparing plugin: %s", name)

        for dependency in mod.GetDependencies():
            if not os.path.exists(dependency):
                logging.error("dependency [%s] does not exist, plugin may not work properly",
                              dependency)
        for path, handler in mod.GetHandlers():
            # websockets are currently not used
            if "websocket" in path:
                handlers.append((path, handler))
            else:
                handlers.append((path, handler, {"template_args": template_args}))
    return handlers

def main():

    # Trigger reload when we change some crucuial files
    # which are not known to the automatic
    tornado.autoreload.watch("static/hocuspocus.css")
    tornado.autoreload.watch("hocuspocus.conf")

    tornado.options.parse_command_line()

    plugins = LoadPlugins(ALL_PLUGINS)

    # delay this until after the plugins have been loaded
    # so that the plugin options are known
    tornado.options.parse_config_file("hocuspocus.conf")

    handlers = GetHandlers(plugins)

    logging.info("Installing Handlers:")
    for h in handlers:
        logging.info("%s: %s", h[0], h[1])

    application = tornado.web.Application(
        handlers,
        debug=True,
        task_pool=multiprocessing.Pool(OPTIONS.tasks),
        template_path="Templates/",
        static_path="Static/")


    logging.info("listening on port %d", OPTIONS.port)
    application.listen(OPTIONS.port)
    tornado.ioloop.IOLoop.instance().start()
    return 0

if __name__ == "__main__":

    sys.exit(main())
